import axios from 'axios'
import { Message } from 'element-ui'
import store from '@/store'
import router from '@/router'
// create an axios instance
const service = axios.create({
  // 请求基地址
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  // withCredentials: true, // send cookies when cross-domain requests
  timeout: 5000 // 设置请求超时时间(单位：毫秒) 这里表示请求超过5秒还没有成功，则直接报错请求超时的错误
})

const time = 24 * 60 * 60 * 1000 // 规定token有效时长 1天
// 请求拦截器
service.interceptors.request.use(config => {
  // 统一设置请求头 传token给后端
  const { token } = store.state.user
  if (token) {
    // 计算用户的登录时长  =  当前时间戳 - 登录的时间戳
    const timeLong = Date.now() - localStorage.getItem('loginTime')
    if (timeLong > time) {
      // token过期了
      // 退出登录
      store.dispatch('user/logout')
      // 跳转到登录页面
      router.push('/login')
      // 阻止代码继续运行 并 返回一个错误信息
      // 这个错误信息将会在响应拦截器的错误回调函数中接收到
      return Promise.reject(new Error('token失效！--- 前端设置'))
    }

    config.headers.Authorization = `Bearer ${token}`
  }
  return config // 放行
})

// 响应拦截器
service.interceptors.response.use(
  // 网络层面成功的回调函数
  (response) => {
    // 数据层面失败处理，当数据层面请求失败的时候 后端会返回success字段给我们并且值为false
    // if(response.data.success==false){
    const { success, message } = response.data
    if (!success) {
      // 失败  -- 提示用户  阻止跳转到首页
      Message.error(message)
      // 返回一个正确的报错信息
      // promise是原生js（es6）的语法
      // Promise.reject() 方法返回一个带有拒绝原因的 Promise 对象
      // 拒绝就是阻止的意思，也就是当调用接口 得到Promise.reject(message)对象的时候
      // 代码就不会继续往下执行了
      // new Error 是原生js的方法，返回一个包含错误位置的错误对象，并且会报错误的信息包裹在这个对象中
      // console.dir(new Error(message))
      return Promise.reject(new Error(message))
    } else {
      // 数据层面成功处理
      // 用户操作成功-添加统一提示用户  --- get请求除外
      if (response.config.method !== 'get') {
        // 当请求方式不等于get的时候才需要显示 提示语
        Message.success(message)
      }
      return response
    }
  },
  // 网络层面失败
  (err) => {
    console.dir(err)
    // 当token过期的时候 调用接口后端会返回code值为10002给我们
    // 因此我们就可以通过code来判断token是否失效
    // 这里需要做一个短路运算判断，因为response属性只有当后端返回错误信息的才有的
    // 当我们自定义请求错误信息的时候，是没有response属性的
    if (err.response && err.response.data.code === 10002) {
      // token过期了
      Message.error('登录超时了！')
      // 退出登录
      store.dispatch('user/logout')
      // 跳转到登录页
      router.push('/login')
      return Promise.reject(err)
    }
    // 提示错误信息
    Message.error(err.message)
    // 阻止页面跳转
    return Promise.reject(err)
  }
)

export default service
